import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:dio/dio.dart' as dio;

/// 缓存管理器，用于管理网络资源的下载和缓存
///
/// 使用单例模式确保全局只有一个缓存管理器实例
/// 提供文件缓存、下载和缓存清理功能
class CacheManager {
  static final CacheManager _instance = CacheManager._internal();

  /// 获取缓存管理器单例实例
  factory CacheManager() => _instance;

  /// 私有构造函数
  CacheManager._internal();

  /// 获取缓存目录路径
  ///
  /// 返回应用临时目录路径，用于存储缓存文件
  Future<String> get _cacheDirPath async {
    final dir = await getTemporaryDirectory();
    return dir.path;
  }

  /// 获取缓存文件路径
  ///
  /// [url] 资源URL
  /// 返回缓存文件路径，如果文件不存在则返回null
  Future<String?> getCachedFilePath(String url) async {
    final cacheDir = await _cacheDirPath;
    final fileName = _getFileNameFromUrl(url);
    final filePath = p.join(cacheDir, fileName);
    final file = File(filePath);
    return file.existsSync() ? filePath : null;
  }

  /// 下载并缓存文件
  ///
  /// [url] 要下载的资源URL
  /// 返回缓存文件路径
  /// 如果文件已存在则直接返回路径，否则下载并缓存
  /// 抛出异常当下载失败时
  Future<String> downloadAndCacheFile(String url) async {
    final cacheDir = await _cacheDirPath;
    final fileName = _getFileNameFromUrl(url);
    final filePath = p.join(cacheDir, fileName);
    final file = File(filePath);

    if (file.existsSync()) {
      return filePath;
    }

    final client = dio.Dio();
    final response = await client.download(url, filePath);
    if (response.statusCode != 200) {
      throw Exception('下载失败: ${response.statusCode}');
    }

    return filePath;
  }

  /// 清空缓存
  ///
  /// 删除缓存目录中的所有文件
  Future<void> clearCache() async {
    final cacheDir = await _cacheDirPath;
    final dir = Directory(cacheDir);
    if (dir.existsSync()) {
      dir.deleteSync(recursive: true);
    }
  }

  /// 从URL中提取文件名
  ///
  /// [url] 资源URL
  /// 返回URL路径中的最后一个部分作为文件名，如果没有则使用时间戳
  String _getFileNameFromUrl(String url) {
    final uri = Uri.parse(url);
    final pathSegments = uri.pathSegments;
    return pathSegments.isNotEmpty ? pathSegments.last : '${DateTime.now().millisecondsSinceEpoch}.flac';
  }
}